package com.kld.third.service.impl.tenpay;

import com.kld.third.PayMethod.RequestHandler;
import com.kld.third.PayMethod.ResponseHandler;
import com.kld.third.PayMethod.api.ITenpayServcie;
import com.kld.third.PayMethod.client.ClientResponseHandler;
import com.kld.third.PayMethod.client.TenpayHttpClient;
import com.kld.third.PayMethod.dto.TenPayDto;
import com.kld.third.PayMethod.util.TenpayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2016/3/31.
 */
public class TenPayServiceImpl implements ITenpayServcie  {
    private Logger logger = LoggerFactory.getLogger(TenPayServiceImpl.class);
    @Override
    public String payRequest(TenPayDto tenPayDto,HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException{
        String partner =tenPayDto.getPartner();//商务号------------数据库获取待定
        String key =tenPayDto.getSignKeyIndex();//密钥-------------------数据库获取待定

        //交易完成后跳转的URL
        String return_url = "http://127.0.0.1:8080/tenpay_api_b2c/payReturnUrl.jsp";
        //接收财付通通知的URL
        String notify_url = "http://127.0.0.1:8080/tenpay_api_b2c/payNotifyUrl.jsp";

        //---------------生成订单号 开始------------------------
        //当前时间 yyyyMMddHHmmss
        String currTime = TenpayUtil.getCurrTime();
        //8位日期
        //String strTime = currTime.substring(8, currTime.length());
        //四位随机数
        // String strRandom = TenpayUtil.buildRandom(4) + "";
        //10位序列号,可以自行调整。
        //  String strReq = strTime + strRandom;
        //订单号，此处用时间加随机数生成，商户根据自己情况调整，只要保持全局唯一就行
        //String out_trade_no = strReq;
//---------------生成订单号 结束------------------------

        //创建支付请求对象
        RequestHandler reqHandler = new RequestHandler(request, response);
        reqHandler.init();
        //设置密钥
        reqHandler.setKey(key);
        reqHandler.setGateUrl("https://gw.tenpay.com/gateway/pay.htm");

//-----------------------------
//设置支付参数
//-----------------------------
        if(tenPayDto.getBankType()!=null){
            reqHandler.setParameter("bank_type",tenPayDto.getBankType());
        }
        reqHandler.setParameter("body",tenPayDto.getBody());
        if(tenPayDto.getAttach()!=null) {
            reqHandler.setParameter("attach",tenPayDto.getAttach());
        }
        reqHandler.setParameter("return_url",tenPayDto.getReturnUrl());
        reqHandler.setParameter("notify_url",tenPayDto.getNotifyUrl());
        if(tenPayDto.getBuyerId()!=null) {
            reqHandler.setParameter("buyer_id", tenPayDto.getBuyerId());
        }
        reqHandler.setParameter("partner",tenPayDto.getPartner());
        reqHandler.setParameter("out_trade_no",tenPayDto.getOutTradeNo());
        reqHandler.setParameter("total_fee",tenPayDto.getTotalFee()+"");
        reqHandler.setParameter("fee_type",tenPayDto.getFeeType()+"");
        reqHandler.setParameter("spbill_create_ip",tenPayDto.getSpbillCreateIp());
        if(tenPayDto.getTimeStart()!=null) {
            reqHandler.setParameter("time_start",tenPayDto.getTimeStart());
        }
        if(tenPayDto.getTimeExpire()!=null) {
            reqHandler.setParameter("time_expire",tenPayDto.getTimeExpire());
        }
        if (tenPayDto.getTransportFee()!=null) {
            reqHandler.setParameter("transport_fee",tenPayDto.getTransportFee()+"");
        }
        if(tenPayDto.getProductFee()!=null)
        reqHandler.setParameter("product_fee",tenPayDto.getProductFee()+"");
        if (tenPayDto.getGoodsTag()!=null)
        reqHandler.setParameter("goods_tag",tenPayDto.getGoodsTag());


//        reqHandler.setParameter("partner", partner);		            //商户号
//     //   reqHandler.setParameter("out_trade_no", out_trade_no);		//商家订单号
//        reqHandler.setParameter("total_fee", "1");			        //商品金额,以分为单位
//        reqHandler.setParameter("return_url", return_url);		    //交易完成后跳转的URL
//        reqHandler.setParameter("notify_url", notify_url);		    //接收财付通通知的URL
//        reqHandler.setParameter("body", "测试");	                    //商品描述
//        reqHandler.setParameter("bank_type", "DEFAULT");		    //银行类型
//        reqHandler.setParameter("spbill_create_ip",request.getRemoteAddr());   //用户的公网ip
//        reqHandler.setParameter("fee_type", "1");
//
////系统可选参数
//        reqHandler.setParameter("sign_type", "MD5");
//        reqHandler.setParameter("service_version", "1.0");
//        reqHandler.setParameter("input_charset", "GBK");
//        reqHandler.setParameter("sign_key_index", "1");
//
////业务可选参数
//        reqHandler.setParameter("attach", "");
//        reqHandler.setParameter("product_fee", "1");
//        reqHandler.setParameter("transport_fee", "0");
//        reqHandler.setParameter("time_start", currTime);
//        reqHandler.setParameter("time_expire", "");
//
//        reqHandler.setParameter("buyer_id", "");
//        reqHandler.setParameter("goods_tag", "");
        //reqHandler.setParameter("agentid", "");
        //reqHandler.setParameter("agent_type", "");

        //请求的url
        String requestUrl = null;
        requestUrl = reqHandler.getRequestURL();

        //获取debug信息,建议把请求和debug信息写入日志，方便定位问题
        String debuginfo = reqHandler.getDebugInfo();
        logger.info("财付通扣款请求debug信息"+debuginfo);
        logger.info("财付通扣款请求url"+requestUrl);
        System.out.println("requestUrl:" + requestUrl);
        return requestUrl;
    }

    @Override
    public void payNotifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception{

        ResponseHandler resHandler = new ResponseHandler(request, response);
        if(resHandler.isTenpaySign()) {

            //通知id
            String notify_id = resHandler.getParameter("notify_id");
            //商户号
            String partner =  resHandler.getParameter("partner");
            //key     通过商务号数据库查询出改密钥
            String key="8934e7d15453e97507ef794cf7b0519d";

            //创建请求对象
            RequestHandler queryReq = new RequestHandler(null, null);
            //通信对象
            TenpayHttpClient httpClient = new TenpayHttpClient();
            //应答对象
            ClientResponseHandler queryRes = new ClientResponseHandler();

            //通过通知ID查询，确保通知来至财付通
            queryReq.init();
            queryReq.setKey(key);
            queryReq.setGateUrl("https://gw.tenpay.com/gateway/verifynotifyid.xml");
            queryReq.setParameter("partner", partner);
            queryReq.setParameter("notify_id", notify_id);

            //通信对象
            httpClient.setTimeOut(5);
            //设置请求内容
            httpClient.setReqContent(queryReq.getRequestURL());
            System.out.println("queryReq:" + queryReq.getRequestURL());
            //后台调用
            if(httpClient.call()) {
                //设置结果参数
                queryRes.setContent(httpClient.getResContent());
                System.out.println("queryRes:" + httpClient.getResContent());
                queryRes.setKey(key);


                //获取返回参数
                String retcode = queryRes.getParameter("retcode");
                String trade_state = queryRes.getParameter("trade_state");

                String trade_mode = queryRes.getParameter("trade_mode");

                //判断签名及结果
                if(queryRes.isTenpaySign()&& "0".equals(retcode) && "0".equals(trade_state) && "1".equals(trade_mode)) {
                    System.out.println("订单查询成功");
                    //取结果参数做业务处理
                    System.out.println("out_trade_no:" + queryRes.getParameter("out_trade_no")+
                            " transaction_id:" + queryRes.getParameter("transaction_id"));
                    System.out.println("trade_state:" + queryRes.getParameter("trade_state")+
                            " total_fee:" + queryRes.getParameter("total_fee"));
                    //如果有使用折扣券，discount有值，total_fee+discount=原请求的total_fee
                    System.out.println("discount:" + queryRes.getParameter("discount")+
                            " time_end:" + queryRes.getParameter("time_end"));
                    //------------------------------
                    //处理业务开始
                    //------------------------------

                    //处理数据库逻辑
                    //注意交易单不要重复处理
                    //注意判断返回金额

                    //------------------------------
                    //处理业务完毕
                    //------------------------------
                    resHandler.sendToCFT("Success");
                }
                else{
                    //错误时，返回结果未签名，记录retcode、retmsg看失败详情。
                    System.out.println("查询验证签名失败或业务错误");
                    System.out.println("retcode:" + queryRes.getParameter("retcode")+
                            " retmsg:" + queryRes.getParameter("retmsg"));
                }

            } else {

                System.out.println("后台调用通信失败");

                System.out.println(httpClient.getResponseCode());
                System.out.println(httpClient.getErrInfo());
                //有可能因为网络原因，请求已经处理，但未收到应答。
            }
        }
        else{
            System.out.println("通知签名验证失败");
        }
    }

    @Override
    public Map<String, String> normalOrderQuery(Map<String,String> map)throws Exception {
        Map<String,String> map1=new HashMap<>();
        //商户号  数据库查询
        String partner = "1900000109";

        //密钥 数据库查询
        String key = "8934e7d15453e97507ef794cf7b0519d";

        //创建查询请求对象
        RequestHandler reqHandler = new RequestHandler(null, null);
        //通信对象
        TenpayHttpClient httpClient = new TenpayHttpClient();
        //应答对象
        ClientResponseHandler resHandler = new ClientResponseHandler();

        //-----------------------------
        //设置请求参数
        //-----------------------------
        reqHandler.init();
        reqHandler.setKey(key);
        reqHandler.setGateUrl("https://gw.tenpay.com/gateway/normalorderquery.xml");

        //-----------------------------
        //设置接口参数
        //-----------------------------
        reqHandler.setParameter("partner", partner);    //商户号

        //out_trade_no和transaction_id至少一个必填，同时存在时transaction_id优先
        String outTradeNo=map.get("outTradeNo");
        reqHandler.setParameter("out_trade_no", outTradeNo);    	    	                //商家订单号
        //reqHandler.setParameter("transaction_id", "1900000109201101270026218385");	//财付通交易单号

        //-----------------------------
        //设置通信参数
        //-----------------------------
        //设置请求返回的等待时间
        httpClient.setTimeOut(5);

        //设置请求内容
        String requestUrl = reqHandler.getRequestURL();
        httpClient.setReqContent(requestUrl);
        String rescontent = "null";

        //后台调用
        if(httpClient.call()) {
            //设置结果参数
            rescontent = httpClient.getResContent();
            resHandler.setContent(rescontent);
            resHandler.setKey(key);

            //获取返回参数
            String retcode = resHandler.getParameter("retcode");

            //判断签名及结果
            if(resHandler.isTenpaySign()&& "0".equals(retcode)) {
                System.out.println("订单查询成功</br>");
                //返回状态码
                String retcode1 = resHandler.getParameter("retcode");
                map1.put("retcode", retcode1);
                //返回状态码
                String tradeState = resHandler.getParameter("trade_state");
                map1.put("tradeState",tradeState);
                //返回信息
                String retMsg = resHandler.getParameter("retmsg");
                map1.put("retMsg",retMsg);
                //交易模式
                String tradeMode = resHandler.getParameter("trade_mode");
                map1.put("tradeMode",tradeMode);
                //商户号
                String partner1 = resHandler.getParameter("partner");
                map1.put("partner",partner1);
                //付款银行
                String bankType = resHandler.getParameter("bank_type");
                map1.put("bankType",bankType);
                //银行订单号
                String bankBillno = resHandler.getParameter("bank_billno");
                map1.put("bankBillno",bankBillno);
                //总金额
                String totalFee = resHandler.getParameter("total_fee");
                map1.put("totalFee",totalFee);
                //币种
                String feeType = resHandler.getParameter("fee_type");
                map1.put("feeType",feeType);
                //财付通订单号
                String transactionId = resHandler.getParameter("transaction_id");
                map1.put("transactionId",transactionId);
                //商户订单号
                String outTradeNo1 = resHandler.getParameter("out_trade_no");
                map1.put("outTradeNo",outTradeNo1);
                //是否分账
                String isSplit = resHandler.getParameter("is_split");
                map1.put("isSplit",isSplit);
                //是否退款
                String isRefund = resHandler.getParameter("is_refund");
                map1.put("isRefund",isRefund);
                //商家数据包
                String attach = resHandler.getParameter("attach");
                map1.put("attach",attach);
                //支付完成时间
                String timeEnd = resHandler.getParameter("time_end");
                map1.put("timeEnd",timeEnd);
                //物流费用
                String transportFee = resHandler.getParameter("transport_fee");
                map1.put("transportFee",transportFee);
                //物品费用
                String productFee = resHandler.getParameter("product_fee");
                map1.put("productFee",productFee);
                //折扣掉价格
                String discount = resHandler.getParameter("discount");
                map1.put("discount",discount);
                //买家别名
                String buyerAlias = resHandler.getParameter("buyer_alias");
                map1.put("buyerAlias",buyerAlias);
                //彩贝积分金额
                String cashTicketFee = resHandler.getParameter("cash_ticket_fee");
                map1.put("cashTicketFee",cashTicketFee);
            } else {
                //错误时，返回结果未签名，记录retcode、retmsg看失败详情。
                System.out.println("验证签名失败或业务错误");
                System.out.println("retcode:" + resHandler.getParameter("retcode")+
                        " retmsg:" + resHandler.getParameter("retmsg"));
            }
        } else {
            System.out.println("后台调用通信失败");
            System.out.println(httpClient.getResponseCode());
            System.out.println(httpClient.getErrInfo());
            //有可能因为网络原因，请求已经处理，但未收到应答。
        }

        //获取debug信息,把请求、应答内容、debug信息，通信返回码写入日志，方便定位问题
        logger.info("http res:" + httpClient.getResponseCode() + "," + httpClient.getErrInfo());
        logger.info("req url:" + requestUrl);
        logger.info("req debug:" + reqHandler.getDebugInfo());
        logger.info("res content:" + rescontent);
        logger.info("res debug:" + resHandler.getDebugInfo());
        return  map1;
    }
}
